/**
 * Bilibili下载器 - 后台脚本
 * 
 * 负责处理以下功能：
 * 1. 与内容脚本通信，获取视频信息
 * 2. 管理下载队列
 * 3. 处理视频下载和格式转换
 * 4. 保存用户设置
 */

// 下载队列管理
/** @type {Array} 下载队列 */
const downloadQueue = [];
/** @type {boolean} 是否正在下载 */
let isDownloading = false;
/** @type {Object} 当前下载信息 */
let currentDownload = null;
/** @type {Object} 下载状态和进度信息 */
let downloadStatus = {
  progress: 0,
  speed: 0,
  startTime: 0,
  timeRemaining: 0
};

// 存储最近一次获取的视频信息
/** @type {Object|null} 最近获取的视频信息 */
let recentVideoInfo = null;

/**
 * 初始化扩展
 */
function initExtension() {
  // 监听来自内容脚本的消息
  chrome.runtime.onMessage.addListener(handleMessages);
  
  // 监听下载事件
  chrome.downloads.onChanged.addListener(onDownloadChanged);
  
  // 初始化配置
  initializeSettings();
}

/**
 * 初始化用户设置
 */
function initializeSettings() {
  // 获取保存的设置，如果没有则使用默认设置
  chrome.storage.local.get({
    defaultFormat: 'mp4',
    defaultQuality: '720',
    customDownloadPath: '',
    downloadHistory: []
  }, (settings) => {
    // 确保下载历史记录存在
    if (!settings.downloadHistory) {
      chrome.storage.local.set({ downloadHistory: [] });
    }
  });
}

/**
 * 处理接收到的消息
 * @param {Object} message - 消息对象
 * @param {Object} sender - 发送者信息
 * @param {Function} sendResponse - 回复函数
 * @returns {boolean} 是否继续处理
 */
function handleMessages(message, sender, sendResponse) {
  switch (message.action) {
    case 'getVideoInfo':
      // 从storage中获取并发送之前的设置
      chrome.storage.local.get({
        defaultFormat: 'mp4',
        defaultQuality: '720',
        customDownloadPath: ''
      }, (settings) => {
        sendResponse({
          success: true,
          settings: settings
        });
      });
      return true; // 异步响应
      
    case 'startDownload':
      handleDownloadRequest(message.videoInfo, message.options);
      sendResponse({ success: true });
      break;
      
    case 'getDownloadProgress':
      sendResponse({
        isDownloading: isDownloading,
        currentDownload: currentDownload,
        downloadStatus: downloadStatus,
        queue: downloadQueue.length
      });
      break;
      
    case 'cancelDownload':
      if (currentDownload && currentDownload.downloadId) {
        chrome.downloads.cancel(currentDownload.downloadId);
        isDownloading = false;
        currentDownload = null;
        processNextInQueue();
      }
      sendResponse({ success: true });
      break;
      
    case 'getDownloadHistory':
      chrome.storage.local.get({ downloadHistory: [] }, (data) => {
        sendResponse({ history: data.downloadHistory });
      });
      return true; // 异步响应
      
    case 'clearDownloadHistory':
      chrome.storage.local.set({ downloadHistory: [] });
      sendResponse({ success: true });
      break;
      
    case 'saveSettings':
      chrome.storage.local.set({
        defaultFormat: message.settings.format,
        defaultQuality: message.settings.quality,
        customDownloadPath: message.settings.downloadPath
      });
      sendResponse({ success: true });
      break;
      
    // 新增：处理显示下载面板的消息
    case 'showDownloadPanel':
      // 这个消息用于打开弹出窗口，但实际上由于Chrome扩展API限制，
      // 内容脚本无法直接打开弹出窗口，这里我们可以使用通知
      // 提醒用户点击扩展图标
      chrome.notifications.create({
        type: 'basic',
        iconUrl: 'images/icon128.png',
        title: 'Bilibili下载器',
        message: '请点击扩展图标打开下载面板'
      });
      sendResponse({ success: true });
      break;
      
    // 新增：处理从页面提取的视频信息
    case 'videoInfoExtracted':
      // 存储最近获取的视频信息，以便弹出窗口使用
      recentVideoInfo = message.videoInfo;
      // 更新视频信息到存储中，便于弹出窗口读取
      chrome.storage.local.set({ recentVideoInfo: recentVideoInfo });
      sendResponse({ success: true });
      break;
  }
}

/**
 * 处理下载请求
 * @param {Object} videoInfo - 视频信息
 * @param {Object} options - 下载选项
 */
function handleDownloadRequest(videoInfo, options) {
  // 创建下载项
  const downloadItem = {
    id: generateUniqueId(),
    videoInfo: videoInfo,
    options: options,
    status: 'queued',
    progress: 0,
    addedTime: Date.now()
  };
  
  // 添加到下载队列
  downloadQueue.push(downloadItem);
  
  // 如果当前没有下载任务，开始下载
  if (!isDownloading) {
    processNextInQueue();
  }
  
  // 更新下载历史
  updateDownloadHistory(downloadItem);
}

/**
 * 处理队列中的下一个下载任务
 */
function processNextInQueue() {
  if (downloadQueue.length === 0) {
    isDownloading = false;
    currentDownload = null;
    return;
  }
  
  isDownloading = true;
  currentDownload = downloadQueue.shift();
  currentDownload.status = 'downloading';
  
  // 重置下载状态
  downloadStatus = {
    progress: 0,
    speed: 0,
    startTime: Date.now(),
    timeRemaining: 0
  };
  
  // 基于选项准备下载链接
  prepareDownloadUrl(currentDownload.videoInfo, currentDownload.options)
    .then(downloadUrl => {
      if (!downloadUrl) {
        currentDownload.status = 'error';
        processNextInQueue();
        return;
      }
      
      // 设置文件名
      const fileName = sanitizeFileName(currentDownload.videoInfo.title);
      const fileExt = currentDownload.options.format === 'mp3' ? '.mp3' : '.mp4';
      
      // 开始下载
      chrome.downloads.download({
        url: downloadUrl,
        filename: fileName + fileExt,
        saveAs: false
      }, (downloadId) => {
        if (chrome.runtime.lastError) {
          console.error("下载错误:", chrome.runtime.lastError);
          currentDownload.status = 'error';
          processNextInQueue();
        } else {
          currentDownload.downloadId = downloadId;
        }
      });
    })
    .catch(error => {
      console.error("准备下载链接时出错:", error);
      currentDownload.status = 'error';
      processNextInQueue();
    });
}

/**
 * 准备下载URL（实际项目中需要实现解析视频真实地址的逻辑）
 * @param {Object} videoInfo - 视频信息
 * @param {Object} options - 下载选项
 * @returns {Promise<string>} 下载URL
 */
function prepareDownloadUrl(videoInfo, options) {
  return new Promise((resolve, reject) => {
    // 注意：这里需要实现真实的获取Bilibili视频下载链接的逻辑
    // 根据不同清晰度和格式获取不同的链接
    // 下面是一个模拟实现
    
    if (!videoInfo || !videoInfo.playUrl) {
      reject(new Error("没有可用的视频播放地址"));
      return;
    }
    
    // 实际开发中，这里需要根据Bilibili的API获取真实的下载链接
    try {
      // 尝试通过Bilibili API获取视频地址
      // 下面是一个模拟实现，实际需要根据Bilibili的加密方式和API进行特定处理
      const bvid = videoInfo.bvid;
      const cid = videoInfo.cid;
      const format = options.format;
      const quality = options.quality;
      
      // 构建API请求URL
      const apiUrl = `https://api.bilibili.com/x/player/playurl?bvid=${bvid}&cid=${cid}&qn=${quality}&fnval=16`;
      
      // 在实际应用中，这里应该通过fetch或XMLHttpRequest请求API获取视频地址
      // 这里简单返回视频的playUrl作为示例
      resolve(videoInfo.playUrl);
    } catch (error) {
      reject(error);
    }
  });
}

/**
 * 处理下载状态变化
 * @param {Object} downloadDelta - 下载状态变化信息
 */
function onDownloadChanged(downloadDelta) {
  if (!currentDownload || currentDownload.downloadId !== downloadDelta.id) {
    return;
  }
  
  if (downloadDelta.state) {
    switch (downloadDelta.state.current) {
      case 'complete':
        currentDownload.status = 'completed';
        updateDownloadHistory(currentDownload);
        processNextInQueue();
        break;
        
      case 'interrupted':
        currentDownload.status = 'error';
        updateDownloadHistory(currentDownload);
        processNextInQueue();
        break;
    }
  }
  
  if (downloadDelta.bytesReceived) {
    const bytesReceived = downloadDelta.bytesReceived.current;
    const totalBytes = downloadDelta.totalBytes?.current || 0;
    
    if (totalBytes > 0) {
      // 更新进度
      const progress = Math.round((bytesReceived / totalBytes) * 100);
      downloadStatus.progress = progress;
      
      // 计算下载速度
      const elapsedTime = (Date.now() - downloadStatus.startTime) / 1000; // 秒
      if (elapsedTime > 0) {
        downloadStatus.speed = bytesReceived / elapsedTime; // 字节/秒
        
        // 计算剩余时间
        if (downloadStatus.speed > 0) {
          const bytesRemaining = totalBytes - bytesReceived;
          downloadStatus.timeRemaining = bytesRemaining / downloadStatus.speed; // 秒
        }
      }
    }
  }
}

/**
 * 更新下载历史记录
 * @param {Object} downloadItem - 下载项
 */
function updateDownloadHistory(downloadItem) {
  chrome.storage.local.get({ downloadHistory: [] }, (data) => {
    let history = data.downloadHistory;
    
    // 查找是否存在相同 ID 的记录
    const existingIndex = history.findIndex(item => item.id === downloadItem.id);
    
    if (existingIndex !== -1) {
      // 更新现有记录
      history[existingIndex] = {
        id: downloadItem.id,
        title: downloadItem.videoInfo.title,
        cover: downloadItem.videoInfo.cover,
        format: downloadItem.options.format,
        quality: downloadItem.options.quality,
        status: downloadItem.status,
        time: Date.now()
      };
    } else {
      // 添加新记录
      history.unshift({
        id: downloadItem.id,
        title: downloadItem.videoInfo.title,
        cover: downloadItem.videoInfo.cover,
        format: downloadItem.options.format,
        quality: downloadItem.options.quality,
        status: downloadItem.status,
        time: Date.now()
      });
      
      // 限制历史记录的数量，保留最近的50条记录
      if (history.length > 50) {
        history = history.slice(0, 50);
      }
    }
    
    chrome.storage.local.set({ downloadHistory: history });
  });
}

/**
 * 生成唯一ID
 * @returns {string} 唯一ID
 */
function generateUniqueId() {
  return Date.now().toString(36) + Math.random().toString(36).substr(2, 5);
}

/**
 * 净化文件名（移除不允许的字符）
 * @param {string} filename - 原始文件名
 * @returns {string} 净化后的文件名
 */
function sanitizeFileName(filename) {
  return filename.replace(/[\\/:*?"<>|]/g, '_').trim();
}

// 初始化扩展
initExtension(); 